package cn.ellacat.game.guess;

import java.util.Collections;
import java.util.List;

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;

import static cn.ellacat.game.guess.Constants.CARD_STACK;

/**
 * @author wjc133
 */
@Slf4j
public class GameController implements GameListener {
    private final IoWrapper ioWrapper = IoWrapper.getInstance();
    private final List<Card> deck = Lists.newArrayList();
    private final Player p1 = new Player();
    private final Player p2 = new Player();

    private Player currentPlayer;
    private Player sidePlayer;

    private boolean init = false;

    /**
     * 初始化
     */
    public void init() {
        if (this.init) {
            log.info("already init.");
            return;
        }
        for (int i = 0; i <= CARD_STACK; i++) {
            final Card card = new Card();
            card.setColor(CardColor.YELLOW);
            card.setType(CardType.NUMBER);
            card.setNumber(i);
            this.deck.add(card);
        }

        final Card yellowUniversalCard = new Card();
        yellowUniversalCard.setColor(CardColor.YELLOW);
        yellowUniversalCard.setType(CardType.UNIVERSAL);
        this.deck.add(yellowUniversalCard);

        for (int i = 0; i <= CARD_STACK; i++) {
            final Card card = new Card();
            card.setColor(CardColor.BLUE);
            card.setType(CardType.NUMBER);
            card.setNumber(i);
            this.deck.add(card);
        }

        final Card blueUniversalCard = new Card();
        blueUniversalCard.setColor(CardColor.YELLOW);
        blueUniversalCard.setType(CardType.UNIVERSAL);
        this.deck.add(blueUniversalCard);

        this.p1.setNickname("wjc133");
        this.p2.setNickname("ashley");

        Game.getInstance().addListener(this);
        this.init = true;
        log.info("card manager init finished.");
    }

    public void shuffle() {
        Collections.shuffle(this.deck);
    }

    @Override
    public String getId() {
        return "cardManager";
    }

    @Override
    public void onGameStart() {
        this.shuffle();
        log.info("洗牌完成");
        this.decideFirstMove();

        while (!this.isGameOver()) {
            this.currentPlayer.round(this.deck, this.sidePlayer.getCards());
            this.switchPlayer();
        }
        // 公布结果
        this.announceWinner();
        Game.getInstance().end();
    }

    private void announceWinner() {
        final Player winner = this.p1.hasHiddenCard() ? this.p1 : this.p2;
        this.ioWrapper.outLine(winner.getNickname() + "赢了");
    }

    private void switchPlayer() {
        this.currentPlayer = this.currentPlayer == this.p1 ? this.p2 : this.p1;
        this.sidePlayer = this.currentPlayer == this.p1 ? this.p2 : this.p1;
    }

    private void decideFirstMove() {
        final int i = RandomUtils.nextInt(0, 1);
        this.currentPlayer = i > 0 ? this.p1 : this.p2;
        this.sidePlayer = this.currentPlayer == this.p1 ? this.p2 : this.p1;
    }

    private boolean isGameOver() {
        final boolean f1 = this.p1.hasCard() && this.p2.hasCard();
        final boolean f2 = !this.p1.hasHiddenCard() || !this.p2.hasHiddenCard();
        return f1 && f2;
    }

    @Override
    public void onGameEnd() {
        this.ioWrapper.outLine("游戏结束");
    }
}
